<!--
  文件名: UserSetting.vue
  描述: 这是一个用户设置界面，用于用户信息修改，账户修改与注销。
  作者: 白紫铜
  创建日期: 2024-03-29
-->
<template>
<div>
  <el-container>
    <el-aside class="aside"></el-aside>
    <el-container>
      <el-aside class="aside_2">
        <el-col :span="24">
          <el-menu class="userSetting_menu" @select="handleMenuSelect">
            <el-row justify="center" align="middle" style="height: 50px;">
              <el-col :span="24" style="text-align: center;">
                <span>用户设置</span>
              </el-col>
            </el-row>
            <el-menu-item class="userSetting_menu_item" index="1">
              用户基本信息修改
            </el-menu-item>
            <el-menu-item class="userSetting_menu_item" index="2">
              头像修改
            </el-menu-item>
            <el-menu-item class="userSetting_menu_item" index="3">
              密码修改
            </el-menu-item>
            <el-menu-item class="userSetting_menu_item" index="4">
              绑定邮箱修改
            </el-menu-item>
            <el-menu-item class="userSetting_menu_item" index="5">
              账户注销
            </el-menu-item>
          </el-menu>
        </el-col>
      </el-aside>
    </el-container>
    <el-main class="main">
      <div style="margin-top: 50px"></div>
      <div v-show="ShowTips">请在左侧选择想要修改的内容</div>
      <el-form :model="userNameData" label-width="auto" style="max-width: 600px" v-show="ShowUsernameForm">
        <el-form-item label="用户名">
          <el-input v-model="userNameData.username"></el-input>
        </el-form-item>
        <el-form-item label="我的签名">
          <el-input v-model="userNameData.introduce" type="textarea"></el-input>
        </el-form-item>
        <el-form-item label="性别">
          <el-radio-group v-model="userNameData.sex">
            <el-radio value="male" size="large">男</el-radio>
            <el-radio value="female" size="large">女</el-radio>
            <el-radio value="serect" size="large">保密</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="生日">
          <el-date-picker
              v-model="userNameData.birthday"
              type="date"
              placeholder="选择日期"
              value-format="YYYY-MM-DD"
              format="YYYY-MM-DD">
          </el-date-picker>
        </el-form-item>
        <el-form-item>
          <el-button class="update_user" type="primary" @click="submitForm">提交修改</el-button>
        </el-form-item>
      </el-form>
      <el-col label-width="auto" style="max-width: 600px" v-show="ShowAvatarForm">
        <div>修改头像</div>
        <div >
          <el-button class="update_user" type="primary" @click="chooseAvatar">选择头像</el-button>
          <el-image :src="imageUrl" style="margin-left: 100px; border-radius: 50%;height: 100px;width: 100px;background-color: #f0f0f0">
          </el-image>
          <div></div>
          <vue-cropper
              ref="cropper"
              v-if="showCropper"
              :img="imageUrl"
              :outputType="'png'"
              :autoCrop="true"
              auto-crop-height="100%"
              auto-crop-width="100%"
              :centerBox="true"
              :fixed="true"
              :canMove="false"
              style="height: 200px;width: 400px;"
          ></vue-cropper>
          <!-- 上传头像的input元素 -->
          <input type="file" ref="avatarInput" style="display: none" @change="handleAvatarChange">
          <!-- 完成按钮 -->
          <div></div>
          <el-button v-if="showCropper" class="update_user" type="primary" @click="handleFinish">完成</el-button>
        </div>
      </el-col>
      <el-col label-width="auto" style="max-width: 600px" v-show="ShowPasswordForm">
        <!-- 步骤条 -->
        <el-steps :active="currentStep">
          <el-step title="第一步" description="输入原密码">
          </el-step>
          <el-step title="第二步" description="输入新密码"></el-step>
          <el-step title="第三步" description="完成"></el-step>
        </el-steps>
        <div style="margin-top: 50px"></div>
        <el-input
            v-model="old_password"
            v-if="currentStep===0"
            placeholder="请输入原密码"
            type="password"
            show-password>
        </el-input>
        <el-input
            v-model="new_password"
            v-if="currentStep===1"
            placeholder="请输入新密码"
            type="password"
            show-password>
        </el-input>
        <el-input
            v-model="determine_password"
            v-if="currentStep===2"
            placeholder="请重新输入新密码"
            type="password"
            show-password>
        </el-input>
        <div style="margin-top: 50px"></div>
        <el-button class="update_user" type="primary" v-if="currentStep < 2" @click="nextStep">下一步</el-button>
        <el-button class="update_user" type="primary" v-else-if="currentStep===2" @click="nextStep">完成</el-button>
        <el-button class="update_user" type="primary" v-else @click="reSet">重新修改</el-button>
      </el-col>
      <el-row>
        <el-col v-show="ShowEmailForm">
          <el-steps :active="emailStep">
            <el-step title="第一步" description="验证原邮箱">
            </el-step>
            <el-step title="第二步" description="验证新邮箱"></el-step>
          </el-steps>
          <div style="margin: 50px;"></div>
          <el-input
              v-model="email"
              v-if="emailStep===0"
              placeholder="请输入原邮箱"
              style="width: 300px">
          </el-input>
          <el-button v-if="emailStep===0"
                     :disabled="waitingForCaptcha"
                     class="update_user"
                     :class="{'waiting': waitingForCaptcha}"
                     @click="getCaptcha">
            {{waitingForCaptcha ? `${countdown}s后重新获取`:"获取验证码"}}</el-button>
          <div style="margin: 50px;"></div>
          <el-input
              v-model="emailCaptcha"
              v-if="emailStep===0"
              placeholder="请输入验证码"
              style="width: 200px">
          </el-input>
          <el-button v-if="emailStep===0" class="update_user" @click="verifyCaptcha">验证邮箱</el-button>
          <el-input
              v-model="NewEmail"
              v-if="emailStep===1"
              placeholder="请输入新邮箱"
              style="width: 300px">
          </el-input>
          <el-button v-if="emailStep===1"
                     class="update_user"
                     :disabled="waitingForCaptchaPlus"
                     :class="{'waiting': waitingForCaptchaPlus}"
                     @click="getCaptchaPlus">
            {{waitingForCaptchaPlus ? `${countdownPlus}s后重新获取`:"获取验证码"}}</el-button>
          <div style="margin: 50px;"></div>
          <el-input
              v-model="NewEmailCaptcha"
              v-if="emailStep===1"
              placeholder="请输入验证码"
              style="width: 200px">
          </el-input>
          <el-button v-if="emailStep===1" class="update_user" @click="verifyCaptchaPlus">验证邮箱</el-button>
        </el-col>
      </el-row>
      <el-row>
      <el-col label-width="auto" style="max-width: 600px" v-show="ShowDeleteUserForm">
        <div style="margin-top: 50px"></div>
        如需注销账号，请验证邮箱
        <el-form-item style="margin-top: 50px" inline>
          <el-input v-model="deleteEmail" style="width: 400px" placeholder="请输入邮箱"></el-input>
          <el-button class="update_user"
                     @click="getCaptchaDelete"
                     :disabled="waitingForCaptchaDelete"
                     :class="{'waiting': waitingForCaptchaDelete}"
          >{{waitingForCaptchaDelete ? `${countdownDelete}s后重新获取`:"获取验证码"}}</el-button>
        </el-form-item>
        <div style="margin-top: 50px"></div>
        <el-input v-model="deleteCaptcha" style="width: 200px" placeholder="请输入验证码"></el-input>
        <div style="margin-top: 50px"></div>
        <el-button class="update_user" @click="verifyCaptchaDelete">验证邮箱</el-button>
        <div style="margin-top: 50px"></div>
        <el-button v-show="ShowDelete" class="update_user" @click="deleteUser">确认注销</el-button>
      </el-col>
      </el-row>
    </el-main>
    <el-aside class="aside"></el-aside>
  </el-container>
</div>
</template>

<script>

import {VueCropper} from "vue-cropper";
import 'vue-cropper/dist/index.css'
import axios from "axios";

export default {
  name:"UserSetting",
  components:{
    VueCropper,
  },
  data(){
    return{
      user_id:"",
      username:"",
      currentUsername:"",
      password:"",
      sex:"",
      birthday:"",
      introduce:"",
      avatar_url:"",
      userNameData:[],
      ShowUsernameForm:false,
      ShowAvatarForm:false,
      ShowEmailForm:false,
      ShowPasswordForm:false,
      ShowDeleteUserForm:false,
      imageUrl:"",
      ShowTips:true,
      showCropper:false,
      userinfo:"",
      currentStep:0,
      showOldPassword:false,
      showNewPassword:false,
      old_password:"",
      new_password:"",
      determine_password:"",
      emailStep:0,
      emailCaptcha:"",
      email:"",
      OldEmail:"",
      NewEmail:"",
      NewEmailCaptcha:"",
      isEmailValid:false,
      isNewEmailValid:false,
      isDeleteEmailValid:false,
      waitingForCaptcha:false,
      waitingForCaptchaPlus:false,
      waitingForCaptchaDelete:false,
      countdown:60,
      countdownPlus:60,
      countdownDelete:60,
      deleteEmail:"",
      deleteCaptcha:"",
      ShowDelete:false,
    }
  },
  created() {
    // 在组件创建时获取动态参数值
  },
  mounted() {
    this.fetchUserInfo()
  },
  methods:{
    fetchUserInfo(){
      const token=localStorage.getItem('token')
      const config={
        headers:{
          Authorization:`Bearer ${token}`
        }
      }
      axios.get('http://localhost:1145/api/all_userinfo',config)
          .then(response=>{
            this.userinfo=response.data;
            this.user_id=this.userinfo.user_id;
            this.userNameData.username=this.userinfo.username;
            this.username=this.userinfo.username;
            this.userNameData.introduce=this.userinfo.introduce;
            this.userNameData.sex=this.userinfo.sex;
            this.userNameData.birthday=this.userinfo.birthday;
            this.imageUrl=this.userinfo.avatarUrl;
            this.OldEmail=this.userinfo.email;
          })
          .catch(error=>{
            this.$message.error("权限不足，请先登录")
            this.$router.push({name:"HomePage"})
            console.log('获取用户信息失败',error)
          })
    },
    handleMenuSelect(index){
      switch (index){
        case '1':
          this.ShowUsernameForm=true;
          this.ShowAvatarForm=false;
          this.ShowPasswordForm=false;
          this.ShowEmailForm=false;
          this.ShowDeleteUserForm=false;
          this.ShowTips=false;
          break;
        case '2':
          this.ShowUsernameForm=false;
          this.ShowAvatarForm=true;
          this.ShowPasswordForm=false;
          this.ShowEmailForm=false;
          this.ShowDeleteUserForm=false;
          this.ShowTips=false;
          break;
        case '3':
          this.ShowUsernameForm=false;
          this.ShowAvatarForm=false;
          this.ShowPasswordForm=true;
          this.ShowEmailForm=false;
          this.ShowDeleteUserForm=false;
          this.ShowTips=false;
          break;
        case '4':
          this.ShowUsernameForm=false;
          this.ShowAvatarForm=false;
          this.ShowPasswordForm=false;
          this.ShowEmailForm=true;
          this.ShowDeleteUserForm=false;
          this.ShowTips=false;
          break;
        case '5':
          this.ShowUsernameForm=false;
          this.ShowAvatarForm=false;
          this.ShowPasswordForm=false;
          this.ShowEmailForm=false;
          this.ShowDeleteUserForm=true;
          this.ShowTips=false;
          break;
      }
    },
    submitForm(){
      const token=localStorage.getItem('token');
      if(this.userNameData.username!==this.userinfo.username)
      {
        this.currentUsername=this.userNameData.username
      }
      if(this.userNameData.username===this.userinfo.username||this.userNameData.username===null)
      {
        this.currentUsername=null;
      }
      axios.post("http://localhost:1145/api/all_userinfo", {
        user_id:this.user_id,
        username:this.currentUsername,
        introduce:this.userNameData.introduce,
        sex:this.userNameData.sex,
        birthday:this.userNameData.birthday
      },{
        headers:{
          Authorization:`Bearer ${token}`
        }
      })
          .then(response=>{
            if(response.data==="用户信息更新完成")
            this.$message.success("用户信息更新完成")
            window.location.reload()
            if(response.data==="用户名已存在，修改失败")
              this.$message.error("用户名已存在，修改失败")
          })
          .catch(error=>{
            this.$message.error("修改失败")
            console.log("提交失败",error)
          })
    },
    chooseAvatar() {
      // 点击按钮时触发，打开文件选择对话框
      this.$refs.avatarInput.click();
    },
    handleAvatarChange(event) {
      // 处理头像文件选择变化事件
      const file = event.target.files[0];
      const allowTypes=['image/png'];
      const maxFileSize=2*1024*1024;
      if (!file) return;
      if(!allowTypes.includes(file.type)){
        this.$message.error("请选择.png格式文件")
        return;
      }
      if(file.size>maxFileSize){
        this.$message.error("请选择大小小于等于2MB的文件")
        return;
      }

      // 使用FileReader读取选中的头像文件，并显示在页面上
      const reader = new FileReader();
      reader.onload = () => {
        this.imageUrl = reader.result;
        this.showCropper = true; // 显示cropper组件
      };
      reader.readAsDataURL(file);
    },
    handleFinish() {
      // 获取裁剪后的头像数据
      this.$refs.cropper.getCropData(data=>{
        this.imageUrl=data;
        // 隐藏cropper组件
        this.showCropper = false;
        const token=localStorage.getItem('token')
        axios.post("http://localhost:1145/api/avatar_upload", {
          user_id:this.user_id,
          avatarUrl:this.imageUrl
        },{
          headers:{
            Authorization:`Bearer ${token}`
          }
        }).then(response=>{
          this.$message.success("修改成功")
          console.log("提交头像成功",response)
        }).catch(error=>{
          this.$message.error("修改失败")
          console.log("提交失败",error)
        })
      })
    },
    nextStep() {
      if (this.currentStep === 0) {
        const token=localStorage.getItem("token")
        axios.get("http://localhost:1145/api/get_password", {
          headers:{
            Authorization:`Bearer ${token}`
          },
          params:{
            user_id:this.user_id
          }
        }).then(response=>{
          this.password=response.data
          if(this.old_password==this.password){
            this.currentStep++;
            this.$message.success("原密码验证成功")
          }else {
            this.$message.error("密码错误，请重新输入")
          }
        }).catch(error=>{
          this.$message.error(error)
        })
        return
      }
      if (this.currentStep === 1) {

        if(this.password!==this.new_password){
        if(this.new_password.length<6||this.new_password.length>20){
          this.$message.error("新密码长度必须在6-20个字符之间，请重新输入")
        }else {
          this.currentStep++;
        }
        }else {
          this.$message.error("新密码不可与老密码相同")
        }
        return;
      }
      if (this.currentStep === 2) {
        if(this.determine_password===this.new_password) {
          this.submitPassword(); // 提交表单的方法示例
        }else {
          this.$message.error("两次密码输入不一致")
        }
      }
    },
    submitPassword(){
      const token=localStorage.getItem('token')
      axios.post("http://localhost:1145/api/update_password",{
        user_id:this.user_id,
        password:this.new_password
      },{
        headers:{
          Authorization:`Bearer ${token}`
        }
      }).then(response=>{
        this.currentStep++;
        this.$message.success("修改密码成功")
        console.log("修改密码成功",response)
      }).catch(error=>{
        this.$message.error("修改失败")
        console.log("修改密码失败",error)
      })

    },
    reSet(){
      // 刷新当前页面
      location.reload();
    },
    getCaptcha(){
      if(this.isEmailValid){
        if(this.email===this.userinfo.email){
        axios.post('http://localhost:1145/sendEmail', {
          email:this.email
        })
            .then(response=>{
              console.log(response.data);
            }).catch(error=>{
          console.error('ERROR:',error)
        })
        this.startCountdown()
        this.$message.success("发送成功")
        console.log("Perform captcha")
        }else {
          this.$message.error("原邮箱输入错误")
        }
      }
      else {
        this.$message.error("请填写正确的邮箱格式")
      }
    },
    startCountdown(){
      this.waitingForCaptcha=true
      let timer=setInterval(()=>{
        if(this.countdown>0){
          this.countdown--;
        }
        else {
          clearInterval(timer)
          this.waitingForCaptcha=false
          this.countdown=60
        }
      },1000)
    },
    startCountdownPlus(){
      this.waitingForCaptchaPlus=true
      let timer=setInterval(()=>{
        if(this.countdownPlus>0){
          this.countdownPlus--;
        }
        else {
          clearInterval(timer)
          this.waitingForCaptchaPlus=false
          this.countdownPlus=60
        }
      },1000)
    },
    startCountdownDelete(){
      this.waitingForCaptchaDelete=true
      let timer=setInterval(()=>{
        if(this.countdownDelete>0){
          this.countdownDelete--;
        }
        else {
          clearInterval(timer)
          this.waitingForCaptchaDelete=false
          this.countdownDeletec=60
        }
      },1000)
    },
    verifyCaptcha(){
      axios.post("http://localhost:1145/verifyCaptcha",{
        email:this.email,
        captcha:this.emailCaptcha,
      }).then(response=>{
        console.log(response.data)
        this.$message.success("验证成功")
        this.emailStep++;
      })
    },
    getCaptchaPlus(){
      if(this.isNewEmailValid){
        if(this.NewEmail!==this.OldEmail){
          axios.post('http://localhost:1145/sendEmail', {
            email:this.NewEmail
          })
              .then(response=>{
                console.log(response.data);
              }).catch(error=>{
            console.error('ERROR:',error)
          })
          this.startCountdownPlus()
          this.$message.success("发送成功")
          console.log("Perform captcha")
        }else {
          this.$message.error("新邮箱不能与原邮箱相同")
        }
      }
      else {
        this.$message.error("请填写正确的邮箱格式")
      }
    },
    verifyCaptchaPlus(){
      axios.post("http://localhost:1145/verifyCaptcha",{
        email:this.NewEmail,
        captcha:this.NewEmailCaptcha,
      }).then(response=>{
        const token=localStorage.getItem("token")
        console.log(response.data)
        this.$message.success("验证成功")
        axios.post("http://localhost:1145/api/update_email",{
          user_id:this.user_id,
          email:this.NewEmail
        },{
          headers:{
            Authorization:`Bearer ${token}`
          }
        }).then(response=>{
          if(response.data==="用户邮箱已存在，更新失败"){
            this.$message.error("用户邮箱已存在，更新失败")
          }
          if(response.data==="用户邮箱更新完成")
          this.$message.success("用户邮箱更新完成")
          this.emailStep++;
        })
      })
    },
    getCaptchaDelete(){
      if(this.isDeleteEmailValid){
        if(this.deleteEmail===this.OldEmail){
          axios.post('http://localhost:1145/sendEmail', {
            email:this.deleteEmail
          })
              .then(response=>{
                console.log(response.data);
              }).catch(error=>{
            console.error('ERROR:',error)
          })
          this.startCountdownDelete()
          this.$message.success("发送成功")
          console.log("Perform captcha")
        }else {
          this.$message.error("邮箱输入错误，请重新输入")
        }
      }
      else {
        this.$message.error("请填写正确的邮箱格式")
      }
    },
    verifyCaptchaDelete(){
      axios.post("http://localhost:1145/verifyCaptcha",{
        email:this.deleteEmail,
        captcha:this.deleteCaptcha,
      }).then(response=>{
        console.log(response.data)
        if(response.data.message==="验证码验证通过"){this.$message.success("验证成功")
          this.ShowDelete=true}
        if(response.data.error==="验证码错误或已过期，请重新输入"){
          this.$message.error("验证码错误或已过期，请重新输入")
        }
      })
    },
    deleteUser(){
      const token=localStorage.getItem("token")
      axios.delete("http://localhost:1145/api/delete_user",{
        data:{
          user_id:this.user_id
        },
        headers:{
          Authorization:`Bearer ${token}`
        }
      }).then(response=>{
        this.$message.success(response.data)
        //清空本地保存的令牌
        localStorage.clear()
        this.isLogin=false
        this.$router.push({name:"HomePage"})
        window.location.reload()
      }).catch(error=>{
        this.$message.error(error)
      })
    },
    validateEMail(){
      const emailPattern = /\S+@\S+\.\S+/;
      this.isEmailValid=emailPattern.test(this.email);
    },
    validateNewEMail(){
      const emailPattern = /\S+@\S+\.\S+/;
      this.isNewEmailValid=emailPattern.test(this.NewEmail);
    },
    validateDeleteEMail(){
      const emailPattern = /\S+@\S+\.\S+/;
      this.isDeleteEmailValid=emailPattern.test(this.deleteEmail);
    },

  },
  watch:{
    email(){
      this.validateEMail()
    },
    NewEmail(){
      this.validateNewEMail()
    },
    deleteEmail(){
      this.validateDeleteEMail()
    }
  }
}
</script>

<style scoped>
.aside{
  width: 200px;
  height: 100%;
  min-height: calc(100vh - 65px);
  overflow-y: auto;
}
.main{
  width: 1050px;
  height: 500px;
  background-color: white;
  box-shadow: 0 8px 16px rgba(0,0,0,0.1);
}
.aside_2{
  background-color: white;
  height: 500px;
  width: 250px;
  box-shadow: 0 8px 16px rgba(0,0,0,0.1)
}
.el-radio{
  --el-radio-input-border-color-hover:#000000;
}
:deep(.el-radio__input.is-checked .el-radio__inner){
  border: black;
  background-color: black;
  color: black;
}
:deep(.el-radio__input.is-checked+.el-radio__label){
  color: #000000;
  font-weight: bold;
}

:deep(.el-date-table-cell__text){
  color: black !important;
}
:deep(.el-date-table){
  --el-datepicker-active-color: #000000 !important;
  --el-datepicker-hover-text-color: #000000 !important;
}
.el-textarea{
  --el-input-focus-border-color:#000000;
}
.userSetting_menu{
  transition: 0.3s ease;
  width: 200px;
}
.userSetting_menu_item:hover{
  background: #EBEDF0;
  color: #606266;
}
.userSetting_menu_item:focus{
  background: #EBEDF0;
  color: #606266;
  font-weight: bold;
}
.update_user{
  color: white;
  background-color: black;
  transition: 0.3s ease;
  border-color: black;
  border-radius: 0;
}
.update_user:hover{
  color: white;
  background-color: #606266;
  border-color: #606266;
}
.update_user:focus{
  color: white;
  background-color: #606266;
  border-color: #606266;
}
.el-menu-item.is-active{
  background: #EBEDF0;
  color: #606266;
  font-weight: bold;
}
.image-slot {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  background: var(--el-fill-color-light);
  color: var(--el-text-color-secondary);
  font-size: 30px;
}
:deep(.el-step__title.is-finish){
  color: #67C23A !important;
}
:deep(.el-step__head.is-finish){
  color: #67C23A !important;
  border-color: #67C23A !important;
}
:deep(.el-step__description.is-finish){
  color: #67C23A !important;
}
.waiting{
  background-color: #acacac;
  cursor: not-allowed;
}
</style>